package org.karelun.gef.dom;

import java.util.List;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.karelun.gef.helper.DOMConstant;
import org.karelun.gef.model.AbstractConnectionModel;
import org.karelun.gef.model.DiagramModel;
import org.karelun.gef.model.Node;
import org.karelun.gef.model.StateModel;
import org.karelun.gef.model.StateChoiceModel;
import org.karelun.gef.model.StateEndModel;
import org.karelun.gef.model.StateStartModel;
import org.karelun.gef.utils.DOMUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class SaveStateDiagram {

	private DiagramModel diagram=null;
	
	public SaveStateDiagram(DiagramModel diagram){
		this.diagram=diagram ;
	}

	public Document writeDocument(){
		Document document = DOMUtils.getDocumentBuilder().newDocument();
		writeContents(document);
		return document;
	}

	private void writeContents(Document document) {
		Element rootEle = DOMUtils.createElement(document, DOMConstant.TAG_stateDiagram);
		rootEle.setAttribute(DOMConstant.ATTR_author, DOMConstant.author);
		writeNodes(rootEle);
		writeConnectios(rootEle);
	}

	private void writeNodes(Element rootEle) {
		if(diagram==null)
			return;
		List<Node> nodes = diagram.getNodes();
		if(nodes==null||nodes.isEmpty())
			return;
		for(Node node:nodes){
			String name = node.getText();
			String tagName=null;
			if(node instanceof StateStartModel)
				tagName=DOMConstant.TAG_start;
			else if(node instanceof StateModel)
				tagName=DOMConstant.TAG_state;
			else if(node instanceof StateChoiceModel)
				tagName=DOMConstant.TAG_choice;
			else if(node instanceof StateEndModel)
				tagName=DOMConstant.TAG_end;
			Element ele = DOMUtils.createElement(rootEle, tagName);
			ele.setAttribute(DOMConstant.ATTR_name, name);
			ele.setAttribute(DOMConstant.ATTR_id, node.getId());
			
			Element locEle = DOMUtils.createElement(ele, DOMConstant.TAG_loc);
			Point loc = node.getLocation();
			locEle.setAttribute(DOMConstant.ATTR_x, String.valueOf(loc.x));
			locEle.setAttribute(DOMConstant.ATTR_y, String.valueOf(loc.y));
			
			Element sizeEle = DOMUtils.createElement(ele, DOMConstant.TAG_size);
			Dimension size = node.getSize();
			sizeEle.setAttribute(DOMConstant.ATTR_height, String.valueOf(size.height));
			sizeEle.setAttribute(DOMConstant.ATTR_width, String.valueOf(size.width));
			
		}
	}

	private void writeConnectios(Element rootEle) {
		if(diagram==null)
			return;
		List<AbstractConnectionModel> conns = diagram.getConnections();
		if(conns==null||conns.isEmpty())
			return ;
		for(AbstractConnectionModel conn:conns){
			Node sourceNode = conn.getSource();
			Node targetNode = conn.getTarget();
			if(canWriteConns(sourceNode,targetNode)){
				Element connEle = DOMUtils.createElement(rootEle, DOMConstant.TAG_connection);
				String name = conn.getName();
				connEle.setAttribute(DOMConstant.ATTR_type, name);
				
				Element sourceEle = DOMUtils.createElement(connEle, DOMConstant.TAG_source);
				sourceEle.setAttribute(DOMConstant.ATTR_sourceNode, sourceNode.getId());
				
				Element targetEle = DOMUtils.createElement(connEle, DOMConstant.TAG_target);
				targetEle.setAttribute(DOMConstant.ATTR_targetNode, targetNode.getId());
			}
		}
	}

	private boolean canWriteConns(Node sourceNode, Node targetNode) {
		if(sourceNode instanceof StateModel||sourceNode instanceof StateStartModel
				 ||sourceNode instanceof StateChoiceModel ||sourceNode instanceof StateEndModel
				 ||targetNode instanceof StateModel||targetNode instanceof StateStartModel
				 ||targetNode instanceof StateChoiceModel ||targetNode instanceof StateEndModel)
			return true;
		
		return false;
	}
	
	
	
	
	
	
	
}
